4장. 잘 만들었는지 채점하기

출처: 『AI 엔지니어링』(Chip Huyen 지음, 한국어판) | 원서: AI Engineering (O'Reilly), 4장 대응

코드는 분위기만 — Python 같은 말은 몰라도 됩니다. 표의 '비유'와 '위험'만 봐도 충분해요.

0장에서 채점(평가)이 이 책의 심장이라고 했다.

이 장은 그 채점을 실제로 어떻게 하는지 푸는 곳이다.

천천히 읽으면 된다.


0. 이 장의 새 단어

0장 용어집에 없는 말만 여기 셋을 미리 풀어 둔다.

이 셋만 알면 이 장은 다 읽힌다.


사실 일관성(factual consistency)

한 문장 뜻 — 모델이 내놓은 답이 주어진 자료, 또는 세상의 진짜 사실과 어긋나지 않는 정도.

일상비유 — 시험 답안 채점. 교과서(자료)에 적힌 그대로 썼으면 맞고, 교과서에 없는 걸 지어냈으면 틀린다.

한 줄 예 —

# 답이 원본 자료와 어긋나지 않는지 점수로 잰다
score = check_consistency(model_answer, 원본_문서)

벤치마크(benchmark)

한 문장 뜻 — 여러 모델을 똑같은 문제지로 풀게 해 점수를 비교하는, 누구나 쓰는 공개 시험지.

일상비유 — 표준 모의고사. 학교마다 다른 시험이 아니라, 다 같은 문제지를 풀게 해서 점수를 한 줄로 세운다.

한 줄 예 —

# 같은 공개 문제지로 모델 A와 B를 풀려 점수를 비교한다
score_a = run_benchmark(model_a, "MMLU")

슬라이스 평가(slice-based evaluation)

한 문장 뜻 — 전체 점수 하나만 보지 않고, 손님 종류·문제 길이 같은 하위 묶음으로 쪼개 각각의 점수를 따로 보는 방법.

일상비유 — 반 평균과 개인 성적표. 반 평균만 보면 잘 보이지만, 한 명씩 쪼개 보면 특정 학생만 바닥인 게 드러난다.

한 줄 예 —

# 전체 점수 말고, 묶음별로 쪼개서 따로 점수를 본다
for 묶음 in ["유료손님", "무료손님"]:
    print(점수(묶음))

(귀납 도입) 이런 적 있죠?

챗봇을 만들어 1년을 돌렸다.

그런데 이게 잘 답하는 건지 아닌지 아무도 모른다.

좋은지 나쁜지를 모르니 어디를 고쳐야 할지도 모른다.

이게 0장에서 말한 채점, 곧 평가가 없을 때 벌어지는 일이다.

그래서 옆 팀은 다른 방법을 썼다.

앱을 만들기 전에 먼저 정했다.

"이 챗봇은 답이 자료와 맞는지를 80점 넘기면 합격으로 본다."

채점 기준을 먼저 박아 두니, 고칠 곳이 점수로 보였다.

# 만들기 전에 합격 기준부터 박는다
기준 = "답이 자료와 어긋나지 않는가"
합격선 = 0.8

기준을 먼저 정하고 시작하는 이 방식을 평가 주도 개발이라 부른다.

집을 짓기 전에 합격 검사 기준부터 정하는 것과 같다.

평가 주도 개발 — 앱을 다 만든 뒤 채점하는 게 아니라, 만들기 전에 채점 기준부터 정해 두는 방식.


이 장에서 딱 3가지만

  1. 모델 채점은 네 갈래로 본다. 잘 아는가(도메인), 잘 지어내지 않는가(사실 일관성), 시킨 대로 하는가(지시 수행), 싸고 빠른가(비용·지연).
  2. 공개 시험지(벤치마크) 1등이 내 앱 1등은 아니다. 시험지가 새 버리거나(데이터 오염) 내 일과 안 맞을 수 있다.
  3. 전체 점수 하나만 믿지 말고, 묶음별로 쪼개 봐라(슬라이스 평가). 평균에 가려진 구멍이 거기서 보인다.

개념 1 — 채점은 네 갈래로 본다

망가지는 장면

번역 챗봇을 만들려고 모델을 골랐다.

답도 빠르고 말투도 좋았다.

그런데 라틴어를 시켰더니 엉터리였다. 이 모델은 라틴어를 배운 적이 없었던 것이다.

채점을 한 갈래(말투)만 보고 고른 탓이다.

비유

신입 면접. 한 가지만 보고 뽑지 않는다.

실력(아는가), 정직함(지어내지 않는가), 말귀(시킨 대로 하는가), 몸값(싸고 빠른가)을 같이 본다.

비유 코드 위험
네 항목 다 채점 점수 = [실력, 정직, 말귀, 몸값] 안전 — 약점이 미리 걸러진다
한 항목만 보고 뽑음 점수 = [말투] 다른 칸이 바닥인 줄 모르고 배포

한 문장 정의 — 모델 채점은 도메인 능력(잘 아는가), 사실 일관성(지어내지 않는가), 지시 수행(시킨 대로 하는가), 비용·지연(싸고 빠른가) 네 갈래로 본다.

기본 규칙: 앱을 만들기 전에 이 네 칸을 먼저 채워라.

예시 폭격

예시 1 — 완성예(다 보여주는 예).

라틴어 번역 챗봇의 네 칸을 다 채워 보면 이렇다.

채점표 = {
    "아는가(도메인)":   "라틴어 번역 100문제 정답률",
    "지어내는가(사실)": "원문에 없는 말 끼워넣지 않는가",
    "시킨 대로(지시)":  "3줄 이내로 답하라는 지시 지키는가",
    "싸고 빠른가(비용)": "한 번 답에 걸린 시간과 돈",
}

네 칸이 다 차 있으니, 어느 칸이 약한지 한눈에 보인다.

예시 2 — 부분완성(빈칸 채우기).

이번엔 법률 요약 챗봇이다. 아래 빈칸을 직접 채워 보자.

채점표 = {
    "아는가(도메인)":   "법률 용어 문제 정답률",
    "지어내는가(사실)": "_______",   # 빈칸: 무엇과 어긋나지 않아야 하나?
    "시킨 대로(지시)":  "조항 번호를 빠뜨리지 않는가",
    "싸고 빠른가(비용)": "계약서 한 건 처리 시간",
}

빈칸 답: "요약문이 원본 계약서와 어긋나지 않는가". 사실 일관성 칸이다.

예시 3 — 독립적용(혼자 해보기).

이제 직접 한다. 고객 지원 챗봇의 네 칸을 백지에서 채워 보자.

힌트만 준다: 아는가는 우리 회사 제품 지식, 지어내는가는 회사 정책과 맞는가, 시킨 대로는 답 길이 제한, 싸고 빠른가는 응답 속도.

네 칸을 다 채웠다면 채점표 만들기는 끝났다.

미니 시나리오 — 이럴 때 이렇게.

"빨리 배포하자, 채점은 나중에"라는 말이 나오면 멈춰라.

만들기 전에 네 칸짜리 채점표부터 그리고 시작한다.

나중에 그리면, 가린 약점이 그대로 손님에게 간다.


개념 2 — 지어내는지부터 챙긴다 (사실 일관성)

망가지는 장면

회사 환불 규정을 챗봇에게 물었다.

말투는 매끄럽고 자신만만했다.

그런데 우리 회사에 없는 규정을 그럴듯하게 지어냈다.

0장에서 본 그 환각이다. 말투가 매끄러워서 더 잘 속는다.

비유

답안지 채점. 두 가지 잣대가 있다.

하나는 펴 준 교과서(자료)와 맞는지, 하나는 세상 상식과 맞는지다.

비유 코드 위험
펴 준 자료와 대조 맞나(답, 우리_문서) 안전 — 자료 근거로 채점
세상 상식과 대조 맞나(답, 공개_지식) 무엇이 진짜 사실인지 가리기 어렵다

한 문장 정의 — 사실 일관성은 답이 펴 준 자료와 어긋나지 않는지(자료 기준), 또는 세상 사실과 어긋나지 않는지(상식 기준)를 채점하는 일이다.

기본 규칙: 자료를 펴 줬으면, 그 자료와 맞는지부터 채점하라.

예시 폭격

예시 1 — 완성예(다 보여주는 예).

요약 챗봇을 채점한다. 원문에 없는 숫자를 답이 지어냈는지 본다.

원문 = "이 계약은 2년간 유효하다."
답   = "이 계약은 5년간 유효하다."   # 원문엔 2년인데 5년이라 지어냄
맞나(답, 원문)  # → 어긋남. 사실 일관성 불합격

원문과 한 글자라도 어긋나면 불합격이다.

예시 2 — 부분완성(빈칸 채우기).

잘못된 채점과 올바른 채점을 견줘 보자. 빈칸을 채워라.

# 잘못된 예: 비싼 똑똑한 채점기로 100% 전부 채점 → 돈 폭발
채점(전체_100퍼센트, 방법="비싼_AI_채점기")

# 올바른 예: 싼 채점기로 전부, 비싼 채점기는 _____ 만
채점(전체_100퍼센트, 방법="싼_채점기")
채점(________,        방법="비싼_AI_채점기")   # 빈칸: 몇 퍼센트?

빈칸 답: "1퍼센트". 싼 걸로 전부 훑고, 비싼 걸로 1퍼센트만 정밀 채점하면 돈과 품질을 같이 잡는다.

예시 3 — 독립적용(혼자 해보기).

직접 해보자. 모델이 특히 잘 지어내는 두 가지 질문 유형이 있다.

힌트: 하나는 자료가 거의 없는 낯선 주제, 하나는 "X가 Y에 대해 뭐라 했나" 인데 사실 X가 말한 적 없는 경우.

이 두 유형을 골라 채점지에 일부러 넣으면, 지어내기를 잘 잡아낸다.

미니 시나리오 — 이럴 때 이렇게.

채점 비용이 무섭다는 말이 나오면, 두 단계로 나눠라.

싼 채점기로 전부 한 번, 비싼 채점기로 1퍼센트만 한 번.

다 비싼 걸로 돌릴 필요가 없다.


개념 3 — 시킨 대로 하는지 본다 (지시 수행)

망가지는 장면

감정을 "긍정/부정/중립" 셋 중 하나로 답하라고 시켰다.

모델은 감정은 제대로 알아봤다.

그런데 "행복/화남" 이라고 엉뚱한 칸 이름으로 답했다.

아는 건 맞는데, 시킨 형식을 안 지킨 것이다.

비유

심부름. 아는 것과 시킨 대로 하는 것은 다르다.

길을 아는 똑똑한 사람도 "왼쪽 가게"라 했는데 오른쪽 가게에 가면 심부름은 실패다.

비유 코드 위험
형식까지 지킴 답 in ["긍정","부정","중립"] 안전 — 받아서 바로 쓴다
알지만 형식 어김 답 == "행복" 똑똑해도 받아 쓸 수 없다

한 문장 정의 — 지시 수행은 모델이 시킨 형식과 제약(정해진 칸 이름, 글자 수, 꼭 넣을 단어 등)을 그대로 지키는지 채점하는 일이다.

기본 규칙: 기계로 자동 검사되는 지시부터 채점하라.

예시 폭격

예시 1 — 완성예(다 보여주는 예).

"답에 'ephemeral' 이라는 단어를 꼭 넣어라"는 지시는 프로그램으로 딱 검사된다.

답 = "It was an ephemeral moment."
"ephemeral" in 답   # → True. 지시 지킴

단어가 들었는지 아닌지 기계가 1초에 확인한다.

예시 2 — 부분완성(빈칸 채우기).

"답을 3줄 이하로 써라"는 지시를 검사하자. 빈칸을 채워라.

답 = "첫째 줄\n둘째 줄\n셋째 줄\n넷째 줄"
줄수 = len(답.split("\n"))
줄수 <= ____   # 빈칸: 몇 이하여야 지킨 건가?

빈칸 답: 3. 줄 수가 4라서 이 답은 지시를 어겼다.

예시 3 — 독립적용(혼자 해보기).

직접 해보자. "기후 변화만 이야기하라" 같은 지시는 기계로 딱 떨어지게 검사하기 어렵다.

힌트: 이런 건 예/아니오로 답할 작은 질문 목록을 만들어 사람이나 AI 채점기가 본다. 예 — (1) 기후 변화 주제인가, (2) 다른 주제로 새지 않았는가.

이렇게 질문 목록으로 쪼개면 흐릿한 지시도 채점된다.

미니 시나리오 — 이럴 때 이렇게.

나쁜 답이 나왔는데 모델 탓인지 헷갈리면, 지시문부터 의심하라.

내가 시키는 말을 흐릿하게 적었을 수 있다.

자기 앱에 맞는 지시로 채점지를 직접 만드는 게 답이다.


개념 4 — 공개 시험지 1등을 곧장 믿지 않는다 (벤치마크와 데이터 오염)

망가지는 장면

공개 시험지 1등 모델을 보고 곧장 우리 챗봇에 박았다.

그런데 우리 일에서는 영 별로였다.

알고 보니 그 모델은 시험지 정답을 미리 외워 점수만 높았다.

시험지 문제가 모델 공부 자료에 새어 들어간 탓이다.

비유

모의고사 1등. 그 1등이 시험지를 미리 입수해 외운 거라면 실력이 아니다.

게다가 그 모의고사는 우리 반 진짜 시험과 과목도 다를 수 있다.

비유 코드 위험
1등을 거름망으로만 씀 후보 = 시험_상위권(모델들) 안전 — 못난 모델만 걸러낸다
1등을 바로 박음 배포(시험_1등) 정답 유출·내 일과 불일치로 실패

한 문장 정의 — 벤치마크는 못난 모델을 걸러내는 출발점일 뿐이고, 시험지 정답이 새어 든 데이터 오염 때문에 1등이 곧 내 앱 최적은 아니다.

데이터 오염 — 채점에 쓰는 공개 시험지 문제가 모델 공부 자료에 섞여 들어가, 실력이 아니라 외워서 점수가 높아지는 일.

기본 규칙: 공개 시험지는 거름망으로만 쓰고, 최종 선택은 내 채점지로 하라.

예시 폭격

예시 1 — 완성예(다 보여주는 예).

한 연구자가 장난삼아, 시험지 정답만 외운 아주 작은 모델을 만들었다.

작은_모델 = 외우게_하기(시험지_정답)
시험_점수(작은_모델)   # → 거대 모델보다 높음. 하지만 실력은 0

점수는 1등인데 진짜 실력은 없다. 데이터 오염의 민낯이다.

예시 2 — 부분완성(빈칸 채우기).

오염을 의심하는 두 가지 방법이 있다. 빈칸을 채워라.

# 방법 1: 시험 문장이 공부 자료에도 똑같이 있나 대조 → 정확하지만 비쌈
오염의심 = 똑같은_문장_있나(시험지, _________)   # 빈칸: 무엇과 대조?

# 방법 2: 모델이 시험 문장을 너무 술술 읽으면 이미 본 것 → 싸지만 덜 정확
오염의심 = 너무_익숙해함(모델, 시험지)

빈칸 답: "공부_자료(학습 데이터)". 시험 문장이 공부 자료에 그대로 있으면 오염 신호다.

예시 3 — 독립적용(혼자 해보기).

직접 판단해 보자. 공개 시험지 1등 모델을 봤다. 바로 배포해도 될까?

힌트: 안 된다. 거름망으로만 쓰고, 내 일에 맞는 채점지를 따로 돌려 최종 결정한다.

이 순서를 지키면 1등의 함정에 안 빠진다.

미니 시나리오 — 이럴 때 이렇게.

"리더보드 1등이니 이걸로 가자"는 말이 나오면 한 단계 더 밟아라.

공개 시험지로 후보 몇 개만 추리고, 내 채점지로 진짜 1등을 가린다.


개념 5 — 평균에 속지 않는다 (슬라이스 평가)

망가지는 장면

챗봇 전체 정답률이 83퍼센트로 나왔다. 합격이라 여겼다.

그런데 무료 손님만 따로 떼어 보니 거기선 60퍼센트였다.

전체 평균이 무료 손님의 낮은 점수를 가려 버린 것이다.

가장 중요한 손님층이 바닥인 줄 평균만 봐서 몰랐다.

비유

반 평균. 반 평균 83점이면 좋아 보인다.

하지만 한 명씩 성적표를 쪼개 보면, 특정 학생만 40점인 게 드러난다.

비유 코드 위험
묶음별로 쪼개 봄 for 묶음 in 손님종류: 점수(묶음) 안전 — 가려진 구멍이 보인다
전체 평균만 봄 점수(전체) 한 묶음이 바닥인 걸 평균이 가린다

한 문장 정의 — 슬라이스 평가는 전체 점수 하나만 보지 않고 손님 종류·문제 길이 같은 하위 묶음으로 쪼개 각각을 따로 채점해, 평균이 가린 약점을 드러내는 방법이다.

기본 규칙: 전체 점수가 좋아도, 묶음별로 한 번 더 쪼개 봐라.

예시 폭격

예시 1 — 완성예(다 보여주는 예).

손님을 유료와 무료로 쪼개 따로 점수를 낸다.

점수("유료손님")   # → 0.92
점수("무료손님")   # → 0.60   여기가 구멍
점수("전체")       # → 0.83   평균이 0.60을 가렸다

전체만 보면 멀쩡한데, 쪼개니 무료 손님 칸이 무너져 있다.

예시 2 — 부분완성(빈칸 채우기).

평균이 거짓말하는 유명한 경우가 있다. 빈칸을 채워라.

# 모델 A: 묶음마다 다 이김. 그런데 전체 평균은 더 낮음
A = {"그룹1": 0.93, "그룹2": 0.73, "전체": 0.78}
B = {"그룹1": 0.87, "그룹2": 0.69, "전체": 0.83}
# 전체만 보면 ___ 가 이기지만, 묶음마다는 ___ 가 다 이긴다

빈칸 답: 전체는 B, 묶음마다는 A. 평균만 믿으면 진짜 더 나은 A를 놓친다. 이 뒤집힘을 심슨의 역설이라 부른다.

예시 3 — 독립적용(혼자 해보기).

직접 골라 보자. 챗봇 평가를 어떤 묶음으로 쪼개면 좋을까.

힌트: 손님 등급(유료/무료), 들어온 길(모바일/웹), 질문 길이(짧음/긺), 오타 있는 질문 등.

내 앱에서 중요한 묶음을 골라 쪼개면, 가려진 구멍이 보인다.

미니 시나리오 — 이럴 때 이렇게.

"전체 점수 합격이니 끝"이라는 말이 나오면 한 번 더 쪼개라.

유료/무료, 짧은/긴 질문으로 나눠 본다.

평균 뒤에 숨은 약한 묶음이 거기서 나온다.


정리

채점은 네 갈래로 본다. 아는가, 지어내지 않는가, 시킨 대로 하는가, 싸고 빠른가.

공개 시험지 1등을 곧장 믿지 말고, 거름망으로만 쓰고 내 채점지로 최종 결정한다.

전체 점수가 좋아도 묶음별로 쪼개(슬라이스) 평균에 가린 구멍을 찾는다.

가장 단순한 행동 규칙 — 앱을 만들기 전에 네 칸짜리 채점표부터 그리고, 자료를 펴 줬으면 그 자료와 맞는지부터 채점하라.

다음 장 예고: 다음 장에서는 모델에게 말을 더 잘 거는 법, 곧 프롬프트를 다듬는 법을 본다. (지금 몰라도 됩니다 — 다음 장에서 풀려요.)

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플